using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;
using Microsoft.Phone.Shell;
using Box2D.XNA;
using BlueGameComponent;
using OpenXLive;
using OpenXLive.Features;

namespace TouchExplode
{
     
    /// <summary>
    /// 这是游戏的主类型
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        public static AdvertisementManager AdMgr = new AdvertisementManager();
        public static XLiveFormManager livemanager;
        public static Texture2D liveBkg;

        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        public BasicEffect basicEffect;
        SpriteFont spriteFont;

        //view
        int width = GameConstant.WindowWidth;
        int height = GameConstant.WindowHeight;

        float viewZoom = GameConstant.Box2dParam.viewZoom;
        Vector2 viewCenter = GameConstant.Box2dParam.viewCenter;
        int tw, th;
        
        //ad
        static readonly string ApplicationId = "f941d124-88b4-43af-849d-b16d34e84bef"; // 如果在实际使用中，需要换成您之前申请的ApplicationId
        static readonly string AdUnitId = "10031223"; //ot
        //static AdvertisementManager AdMgr = new AdvertisementManager();
        
        //screen manager
        ScreenManager screenManager;

        //box2d
        public PhysicsWorld box2dworld;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            // Windows Phone 的默认帧速率为 30 fps。
            TargetElapsedTime = TimeSpan.FromTicks(333333);

            // 延长锁定时的电池寿命。
            InactiveSleepTime = TimeSpan.FromSeconds(1);

            graphics.SupportedOrientations = DisplayOrientation.LandscapeLeft;
            graphics.PreferredBackBufferWidth = width;
            graphics.PreferredBackBufferHeight = height;
            graphics.IsFullScreen = true;

            screenManager = new ScreenManager(this);
            Components.Add(screenManager);

            PhoneApplicationService.Current.Activated += GameActivated;
            PhoneApplicationService.Current.Deactivated += GameDeactivated;
        }

        /// <summary>
        /// 允许游戏在开始运行之前执行其所需的任何初始化。
        /// 游戏能够在此时查询任何所需服务并加载任何非图形
        /// 相关的内容。调用 base.Initialize 将枚举所有组件
        /// 并对其进行初始化。 
        /// </summary>
        protected override void Initialize()
        {
            // TODO: 在此处添加初始化逻辑

            
            
            //AdMgr.Initialize(this, ApplicationId,AdUnitId,400-240,5,480,80);
            //AdMgr.SetVisible(false);

            AudioManager.Initialize(this);
#if DEBUG
            screenManager.AddScreen(new MainMenuScreen(), null);
#else
            screenManager.AddScreen(new LogoScreen(), null);
#endif
            box2dworld = PhysicsWorld.GetInstance();

            AdMgr.Initialize
           (
               this,
               GameConstant.Ad_AppID,
               GameConstant.Ad_UnitID,-
               GameConstant.Ad_Pos_x,
               GameConstant.Ad_Pos_y,
               GameConstant.Ad_Widht,
               GameConstant.Ad_Height
           );
            AdMgr.SetVisible(false);

            GameSession session = XLiveGameManager.CreateSession("rajpQASv6Y5uTkMyDx3J8hHC");
            livemanager = new XLiveFormManager(this, session);
            //manager.NewGameEvent += new EventHandler(manager_NewGameEvent);
            //manager.ResumeGameEvent += new EventHandler(manager_ResumeGameEvent);
            //livemanager.UIExitingEvent += new EventHandler(manager_ExitEvent);
            Components.Add(livemanager);
            //session.CreateSessionCompleted += new AsyncEventHandler(session_CreateCompletedEvent);
            session.Open();

            
            base.Initialize();
        }

        /// <summary>
        /// 对于每个游戏会调用一次 LoadContent，
        /// 用于加载所有内容。
        /// </summary>
        protected override void LoadContent()
        {
            // 创建新的 SpriteBatch，可将其用于绘制纹理。
            spriteBatch = new SpriteBatch(GraphicsDevice);

            Texture2D blanktexture = Content.Load<Texture2D>("Textures/blank");
            SpriteFont font = Content.Load<SpriteFont>("Fonts/MenuFont");
            screenManager.SetAsset(blanktexture, font);

            spriteFont = Content.Load<SpriteFont>("font");
            basicEffect = new BasicEffect(GraphicsDevice);
            basicEffect.VertexColorEnabled = true;

            DebugDraw._device = GraphicsDevice;
            DebugDraw._batch = spriteBatch;
            DebugDraw._font = spriteFont;

            liveBkg = Content.Load<Texture2D>("Textures/OpenXLive");


            Resize(GraphicsDevice.PresentationParameters.BackBufferWidth, GraphicsDevice.PresentationParameters.BackBufferHeight);

            PhysicsWorld.GetInstance().LoadContent(this);//要放在Resize后面

            TouchPanel.EnabledGestures = GestureType.Tap | GestureType.FreeDrag;
            // TODO: 在此处使用 this.Content 加载游戏内容
        }

        /// <summary>
        /// 对于每个游戏会调用一次 UnloadContent，
        /// 用于取消加载所有内容。
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: 在此处取消加载任何非 ContentManager 内容
        }

        /// <summary>
        /// 允许游戏运行逻辑，例如更新全部内容、
        /// 检查冲突、收集输入信息以及播放音频。
        /// </summary>
        /// <param name="gameTime">提供计时值的快照。</param>
        protected override void Update(GameTime gameTime)
        {
            // 允许游戏退出
            //if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
               // this.Exit();

            // TODO: 在此处添加更新逻辑


            //box2dworld.Update(gameTime);

            if (screenManager.GetCurrentScreen() is GameScreen)
            {
                while (TouchPanel.IsGestureAvailable)
                {
                    GestureSample sample = TouchPanel.ReadGesture();
                    if (GestureType.Tap == sample.GestureType)
                    {
                        Vector2 v = ConvertScreenToWorld((int)sample.Position.X, (int)sample.Position.Y);
                        box2dworld.MouseUp(v);
                    }
                }
                /*
                TouchCollection touchCol = TouchPanel.GetState();
                if (touchCol.Count > 0)
                {
                    TouchLocation touch = touchCol[0];
                    if (null != touch)
                    {
                        Vector2 v = ConvertScreenToWorld((int)touch.Position.X, (int)touch.Position.Y);
                        if (TouchLocationState.Pressed == touch.State)
                        {
                            box2dworld.MouseDown(v);
                        }
                        else if (TouchLocationState.Released == touch.State)
                        {
                            box2dworld.MouseUp(v);
                        }
                        else if (TouchLocationState.Moved == touch.State)
                        {
                            box2dworld.MouseMove(v);
                        }
                    }
                }
               */
            }
           
            base.Update(gameTime);
            
           
        }
        
        /// <summary>
        /// 当游戏该进行自我绘制时调用此项。
        /// </summary>
        /// <param name="gameTime">提供计时值的快照。</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.BlueViolet);
            /*
            basicEffect.Techniques[0].Passes[0].Apply();
            box2dworld._debugDraw.FinishDrawShapes();
            // TODO: 在此处添加绘图代码

            spriteBatch.Begin();
            box2dworld._debugDraw.FinishDrawString();
            spriteBatch.End();

            box2dworld.Draw(gameTime);
            */
            base.Draw(gameTime);
        }

        void Resize(int w, int h)
        {
            width = w;
            height = h;

            tw = GraphicsDevice.Viewport.Width;
            th = GraphicsDevice.Viewport.Height;
            int x = GraphicsDevice.Viewport.X;
            int y = GraphicsDevice.Viewport.Y;

            float ratio = (float)tw / (float)th;

            Vector2 extents = new Vector2(ratio * 25.0f, 25.0f);
            extents *= viewZoom;

            Vector2 lower = viewCenter - extents;
            Vector2 upper = viewCenter + extents;

            // L/R/B/T
            basicEffect.Projection = Matrix.CreateOrthographicOffCenter(lower.X, upper.X, lower.Y, upper.Y, -1, 1);
        }

        public Vector2 ConvertScreenToWorld(int x, int y)
        {
            float u = x / (float)tw;
            float v = (th - y) / (float)th;

            float ratio = (float)tw / (float)th;
            Vector2 extents = new Vector2(ratio * 25.0f, 25.0f);
            extents *= viewZoom;

            Vector2 lower = viewCenter - extents;
            Vector2 upper = viewCenter + extents;

            Vector2 p = new Vector2();
            p.X = (1.0f - u) * lower.X + u * upper.X;
            p.Y = (1.0f - v) * lower.Y + v * upper.Y;
            return p;
        }

        public Vector2 ConvertWorldToScreen(float x, float y)
        {
            float ratio = (float)tw / (float)th;
            Vector2 extents = new Vector2(ratio * 25.0f, 25.0f);
            extents *= viewZoom;

            Vector2 lower = viewCenter - extents;
            Vector2 upper = viewCenter + extents;

            float u = (lower.X - x) / ((lower.X - upper.X));
            float v = (lower.Y - y) / ((lower.Y - upper.Y));

            Vector2 p = new Vector2();
            p.X = u * (float)tw;
            p.Y = (1 - v) * (float)th;
            return p;
        }

        private void GameActivated(object sender, ActivatedEventArgs e)
        { 
        }

        private void GameDeactivated(object sender, DeactivatedEventArgs e)
        {
            foreach (BaseScreen screen in screenManager.GetScreens())
            {
                if (screen is GameScreen)
                {
                    if (!(screen as GameScreen).Pause)
                    {
                        (screen as GameScreen).PauseGame();
                        break;
                    }
                }
            }
        }  
    }
}
